package com.bjpowernode.crm.workbench.web.controller;


import com.bjpowernode.crm.commons.constant.Constant;
import com.bjpowernode.crm.commons.domain.ReturnObject;
import com.bjpowernode.crm.commons.utils.DateUtils;
import com.bjpowernode.crm.commons.utils.HSSFUtils;
import com.bjpowernode.crm.commons.utils.UUIDUtils;
import com.bjpowernode.crm.settings.domain.User;
import com.bjpowernode.crm.settings.service.UserService;
import com.bjpowernode.crm.workbench.domain.Activity;
import com.bjpowernode.crm.workbench.domain.Remark;
import com.bjpowernode.crm.workbench.service.ActivityService;
import com.bjpowernode.crm.workbench.service.RemarkService;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.*;

/**
 * @Author:luosheng
 * @Date:2023/1/24 17:41
 * @Description:
 */
@Controller
public class ActivityController {

    @Autowired
    private UserService userService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private RemarkService remarkService;

    @RequestMapping("/workbench/activity/index")
    public String index(HttpServletRequest request) {
        //这个查询是给模态窗口中的下拉菜单使用
        List<User> users = userService.queryAllUsers();

        request.setAttribute("users", users);

        return "/workbench/activity/index";
    }


    /**
     * 添加数据
     *
     * @param activity
     * @return
     */
    @ResponseBody
    @RequestMapping("/workbench/activity/saveCreateActivity")
    public Object saveCreateActivity(Activity activity, HttpSession session) {
        //我们前台传来的数据只有六个 但是我们sql新增的时候要用到九个 所以我们要在这里再给添加三个数据
        //分别是id  时间 和谁创建的
        //这里从session取出登录的信息为创建人
        User user = (User) session.getAttribute(Constant.SESSION_USER);

        activity.setCreateBy(user.getId());
        activity.setCreateTime(DateUtils.formateDateTime(new Date()));
        activity.setId(UUIDUtils.getUUID());

        //这要是对数据库进行增删该的操作就写个异常
        ReturnObject returnObject = new ReturnObject();

        try {
            int i = activityService.saveCreateActivity(activity);
            if (i > 0) {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);

            } else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统繁忙请稍后....(其实就是添加失败)");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统繁忙请稍后....(其实就是添加失败)");
        }
        return returnObject;
    }

    @RequestMapping("/workbench/activity/indexBody")
    @ResponseBody
    public Object queryActivityByConditionForPage(String name, String owner, String startDate, String endDate,

                                                  Integer pageNo, Integer pageSize) {
        System.out.println("执行市场活动页面controller===================");
        //封装参数
        Map<String, Object> map = new HashMap<>();
        // (pageObj.currentPage - 1) * pageObj.rowsPerPage
        pageNo = (pageNo - 1) * pageSize;
        map.put("startDate", startDate);
        map.put("name", name);
        map.put("owner", owner);
        map.put("endDate", endDate);
        map.put("pageNo", pageNo);
        map.put("pageSize", pageSize);

        Set set = map.keySet();
        Iterator it = set.iterator();
        while (it.hasNext()) {
            Object key = it.next();
            Object value = map.get(key);
            System.out.println(key + "=" + value);
        }

        System.out.println("执行市场活动页面controller===================");
        //调用service层方法查询数据
        List<Activity> activities = activityService.queryActivityByConditionForPage(map);
        //查询总条数
        int i = activityService.queryCountOfActivityByCondition(map);
        //根据相应结果返回相应信息
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("activities", activities);
        retMap.put("i", i);

        return retMap;
    }

    @RequestMapping("/workbench/activity/deleteActivityIds")
    @ResponseBody
    public Object deleteActivityIds(String[] id) {
        System.out.println("id参数+++++++++++++++++++++" + id);
        //调用service层方法，删除市场活动
        ReturnObject returnObject = new ReturnObject();
        try {
            int ret = activityService.deleteActivityByIds(id);

            if (ret > 0) {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            } else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统繁忙...(删除失败)");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统繁忙...(删除失败)");
        }
        return returnObject;
    }


    @RequestMapping("/workbench/activity/queryActivityById")
    @ResponseBody
    public Object queryActivityById(String id) {
        //调用service层查询所有数据
        Activity activity = activityService.queryActivityById(id);
        //将查到的信息返回到前台
        return activity;
    }

    /**
     * 当修改模态窗口中点击更新执行次controller
     *
     * @param id
     * @param activity
     * @return
     */
    @RequestMapping(value = "/workbench/activity/saveEditActivity")
    @ResponseBody
    public Object saveEditActivity(String id, Activity activity, HttpSession session) {
        //因为我们数据有两个需要进一步封装 一个是修改的当前时间，另外一个是那个账号修改的
        //我们直接就可以在session中取到登录的当前用户的id
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        activity.setEditBy(user.getId());
        //第二个是当前时间，我们直接调用工具类写好的时间格式就行
        activity.setCreateTime(DateUtils.formateDateTime(new Date()));
        System.out.println(activity + "-------------------------------------------------------");
        ReturnObject returnObject = new ReturnObject();

        try {
            int i = activityService.saveEditActivity(activity);
            if (i > 0) {
                //修改成功
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            } else {
                //修改失败
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统繁忙请稍后....(修改失败)");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统繁忙请稍后....(修改失败)");
        }
        return returnObject;
    }

    @RequestMapping(value = "/workbench/activity/fileDownload")
    public void fileDownload(HttpServletResponse response) throws Exception {
//设置响应类型    可以在网上查找要响应的类型，搜索Content-type 其中application/octet-stream 就是响应的二进制文件
        response.setContentType("application/octet-stream;charset=UTF-8");
        //2.获取输出流
        OutputStream out = response.getOutputStream();

        //3.读取excel文件(InputStream),把输出到浏览器(OutoutStream)
        InputStream is = new FileInputStream("D:\\IO练习1\\serverDir\\studentList.xls");

        //当浏览器接收到响应信息之后,默认情况下,直接在显示窗口中打开响应信息；
        //即使打不开，也会调用应用程序打开，只有实在打不开，才会激活文件下载窗口
        //可以设置响应头信息，使浏览器接收到响应信息之后，直接激活文件下载窗口，即使能打开也不打开
        response.addHeader("Content-Disposition", "attachment;filename=mystudentList.xls");

        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = is.read(buff)) != -1) {
            out.write(buff, 0, len);
        }
        //关闭资源，谁开启的谁关闭,谁new的对象谁关,就比如我们is，我们
        //程序员自己new的自己关，比如out 是谁开的谁关
        is.close();
        out.flush();

    }


    @RequestMapping("/workbench/activity/exportAllActivitys")
    public void exportAllActivitys(HttpServletResponse response) throws IOException {

        //调用service层方法，查询所有市场的市场活动
        List<Activity> activities = activityService.queryAllActivitys();

        //创建exel文件，并且把activityList写到excel文件中
        HSSFWorkbook wb = new HSSFWorkbook();
        //先把表sheet创建出来，
        HSSFSheet sheet = wb.createSheet("市场活动列表");
        //创建表头为第一行,
        HSSFRow row = sheet.createRow(0);
        //第一行的内容就是表头所有的字段
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("ID");
        //第二列内容后面都一样...这里太麻烦但是应该可以使用反射写
        cell = row.createCell(1);
        cell.setCellValue("所有者");

        cell = row.createCell(2);
        cell.setCellValue("名称");

        cell = row.createCell(3);
        cell.setCellValue("开始日期");

        cell = row.createCell(4);
        cell.setCellValue("结束日期");

        cell = row.createCell(5);
        cell.setCellValue("成本");

        cell = row.createCell(6);
        cell.setCellValue("描述");

        cell = row.createCell(7);
        cell.setCellValue("创建时间");

        cell = row.createCell(8);
        cell.setCellValue("创建者");

        cell = row.createCell(9);
        cell.setCellValue("修改时间");

        cell = row.createCell(10);
        cell.setCellValue("修改者");
        //现在上面那些，就相当于创建了一行为Excel"表头的信息"...脑部画面


        //下面遍历activityList，创建HSSFRow对象,生成所有的数据行
        if (activities != null && activities.size() > 0) {
            Activity activity = null;
            for (int i = 0; i < activities.size(); i++) {
                //每次取出来一个市场活动
                activity = activities.get(i);

                //每次遍历处也给activity，生成一行(+1是因为我们表头是下标0也就是第一行)
                row = sheet.createRow(i + 1);
                //每一行都会创建11列，每一列的数据从activity中获取
                cell = row.createCell(0);
                cell.setCellValue(activity.getId());
                //第二列内容后面都一样...这里太麻烦但是应该可以使用反射写
                cell = row.createCell(1);
                cell.setCellValue(activity.getOwner());

                cell = row.createCell(2);
                cell.setCellValue(activity.getName());

                cell = row.createCell(3);
                cell.setCellValue(activity.getStartDate());

                cell = row.createCell(4);
                cell.setCellValue(activity.getEndDate());

                cell = row.createCell(5);
                cell.setCellValue(activity.getCost());

                cell = row.createCell(6);
                cell.setCellValue(activity.getDescription());

                cell = row.createCell(7);
                cell.setCellValue(activity.getCreateTime());

                cell = row.createCell(8);
                cell.setCellValue(activity.getCreateBy());

                cell = row.createCell(9);
                cell.setCellValue(activity.getEditTime());

                cell = row.createCell(10);
                cell.setCellValue(activity.getEditBy());
            }
        }
     /*   System.out.println("测试批量下载------------------------");
        //根据wb对象生成excel文件,
        OutputStream os = new FileOutputStream("D:\\IO练习1\\serverDir\\studentList.xls");
        wb.write(os);
        //关闭资源
        os.close();
        wb.close();*/

        //把生成的excel文件下载到客户端
        response.setContentType("application/octet-stream;charset=UTF-8");
        //设置响应头信息,其中解释:content-disposition 指示如何处理响应内容。attchment：以附件形式下载
        response.addHeader("Content-Disposition", "attachment;filename=activityList.xls");
        ServletOutputStream out = response.getOutputStream();
       /* InputStream is = new FileInputStream("D:\\IO练习1\\serverDir\\studentList.xls");

        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = is.read(buff)) != -1) {
            out.write(buff, 0, len);
        }
        is.close();*/

        //我们上面以前写的是下载好再读取的，我们可以直接从浏览器下载
        //提高效率并且，减去大量代码
        wb.write(out);

        wb.close();
        out.flush();
    }

    @RequestMapping(value = "/workbench/activity/exportAllById")
    public void exportAllById(HttpServletResponse response, String[] id) throws IOException {

        for (String s : id
        ) {
            System.out.println(s);
        }
        //调用service层方法，查询所有市场的市场活动
        List<Activity> activities = activityService.queryAllById(id);

        //创建exel文件，并且把activityList写到excel文件中
        HSSFWorkbook wb = new HSSFWorkbook();
        //先把表sheet创建出来，
        HSSFSheet sheet = wb.createSheet("市场活动列表");
        //创建表头为第一行,
        HSSFRow row = sheet.createRow(0);
        //第一行的内容就是表头所有的字段
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("ID");
        //第二列内容后面都一样...这里太麻烦但是应该可以使用反射写
        cell = row.createCell(1);
        cell.setCellValue("所有者");

        cell = row.createCell(2);
        cell.setCellValue("名称");

        cell = row.createCell(3);
        cell.setCellValue("开始日期");

        cell = row.createCell(4);
        cell.setCellValue("结束日期");

        cell = row.createCell(5);
        cell.setCellValue("成本");

        cell = row.createCell(6);
        cell.setCellValue("描述");

        cell = row.createCell(7);
        cell.setCellValue("创建时间");

        cell = row.createCell(8);
        cell.setCellValue("创建者");

        cell = row.createCell(9);
        cell.setCellValue("修改时间");

        cell = row.createCell(10);
        cell.setCellValue("修改者");
        //现在上面那些，就相当于创建了一行为Excel"表头的信息"...脑部画面


        //下面遍历activityList，创建HSSFRow对象,生成所有的数据行
        if (activities != null && activities.size() > 0) {
            Activity activity = null;
            for (int i = 0; i < activities.size(); i++) {
                //每次取出来一个市场活动
                activity = activities.get(i);

                //每次遍历处也给activity，生成一行(+1是因为我们表头是下标0也就是第一行)
                row = sheet.createRow(i + 1);
                //每一行都会创建11列，每一列的数据从activity中获取
                cell = row.createCell(0);
                cell.setCellValue(activity.getId());
                //第二列内容后面都一样...这里太麻烦但是应该可以使用反射写
                cell = row.createCell(1);
                cell.setCellValue(activity.getOwner());

                cell = row.createCell(2);
                cell.setCellValue(activity.getName());

                cell = row.createCell(3);
                cell.setCellValue(activity.getStartDate());

                cell = row.createCell(4);
                cell.setCellValue(activity.getEndDate());

                cell = row.createCell(5);
                cell.setCellValue(activity.getCost());

                cell = row.createCell(6);
                cell.setCellValue(activity.getDescription());

                cell = row.createCell(7);
                cell.setCellValue(activity.getCreateTime());

                cell = row.createCell(8);
                cell.setCellValue(activity.getCreateBy());

                cell = row.createCell(9);
                cell.setCellValue(activity.getEditTime());

                cell = row.createCell(10);
                cell.setCellValue(activity.getEditBy());
            }
        }

        //把生成的excel文件下载到客户端
        response.setContentType("application/octet-stream;charset=UTF-8");
        //设置响应头信息,其中解释:content-disposition 指示如何处理响应内容。attchment：以附件形式下载
        response.addHeader("Content-Disposition", "attachment;filename=activityList.xls");
        ServletOutputStream out = response.getOutputStream();

        wb.write(out);

        wb.close();
        out.flush();
    }

    /**
     * 测试文件上传功能，其中需要在配置文件 (applicationContext-mvc.xml)中进行配置文件上传解析器
     *
     * @param userName
     * @param multipartFile
     * @return
     */
    @RequestMapping("/workbench/activity/fileUpload")
    @ResponseBody
    public Object fileUpload(String userName, MultipartFile myFile) throws IOException {
        System.out.println("测试-----------userName" + userName);

        //把文件在服务指定的目录中生成一个同样的文件
        File file = new File("D:\\IO练习2\\wang1\\A.xls");
        System.out.println("测试");
        myFile.transferTo(file);
        System.out.println("测试");
        //返回响应信息
        ReturnObject returnObject = new ReturnObject();
        returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
        returnObject.setMessage("上传成功");

        return returnObject;
    }

    /**
     * 实现文件上传功能
     *
     * @param activityFile
     * @return
     */
    @RequestMapping("/workbench/activity/importActivity")
    @ResponseBody
    public Object importActivity(MultipartFile activityFile, HttpSession session, String ceshi) {
        System.out.println("测试++++++++++" + ceshi);
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        //流程:前端发送文件，我们接收到先保存到一个磁盘当中，再进行读取

        ReturnObject returnObject = new ReturnObject();
        try {
            //把浏览器获取的先存进去
           /* String originalFilename = activityFile.getOriginalFilename();//获取一下文件名字
            File file = new File("D:\\IO练习2\\wang1", originalFilename);
            activityFile.transferTo(file);
            System.out.println(originalFilename);
            //根据excel文件解析HSSFWorkbook对象，封装了excel文件的所有信息
            InputStream is = new FileInputStream("D:\\IO练习2\\wang1\\" + originalFilename);*/
            //上面那些操作只是为了读文件写文件到磁盘的操作，我们直接就可以简化直接获取流（简化操作，并且大大提高运行效率）
            InputStream is = activityFile.getInputStream();


            HSSFWorkbook wb = new HSSFWorkbook(is);
            //根据wb获取HSSFSheet对象，封装了一页的所有信息
            HSSFSheet sheet = wb.getSheetAt(0);//页的下标，下标从0开始。依次增加
            //根据sheet获取HSSFRow对象，封装了一行的所有信息
            HSSFRow row = null;
            HSSFCell cell = null;
            Activity activity = null;
            List<Activity> activityList = new ArrayList<>();
            System.out.println(sheet.getLastRowNum());
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {//sheet.getLastRowNum();最后一行的下标（我们这里下标为1，就是总第二行开始获取，因为第一行为表头）
                row = sheet.getRow(i);//行的下标，下标从0开始，依次增加
                activity = new Activity();
                activity.setId(UUIDUtils.getUUID());//id我们程序直接生成
                activity.setOwner(user.getId());//所有者为谁导入的就是谁
                activity.setCreateTime(DateUtils.formateDateTime(new Date()));
                activity.setCreateBy(user.getId());


                System.out.println(row.getLastCellNum());
                for (int j = 0; j < row.getLastCellNum(); j++) {//row.getLastCellNum:最后一行的下标+1
                    //根据row获取HSSFCell对象，封装了一列的所有信息
                    cell = row.getCell(j);//列的下标，下标从0开始依次增加

                    //获取列表中的数据
                    String cellValue = HSSFUtils.getCellValueForStr(cell);
                    System.out.println(cellValue);
                    if (j == 0) {
                        activity.setName(cellValue);
                    } else if (j == 1) {
                        activity.setStartDate(cellValue);
                    } else if (j == 2) {
                        activity.setEndDate(cellValue);
                    } else if (j == 3) {
                        activity.setCost(cellValue);
                    } else if (j == 4) {
                        activity.setDescription(cellValue);
                    }
                }
                //每一行中所有列都封装到一个List的集合中
                activityList.add(activity);
                for (Activity a : activityList) {
                    System.out.println(a.toString());
                }

            }
            for (Activity a : activityList
            ) {
                System.out.println(a);
            }
            //调用service层方法，保存市场活动
            int ret = activityService.saveCreateActivityByList(activityList);
            //只要没异常说明就成功了
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            returnObject.setRetData(ret);
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统繁忙请稍后....(报错了)");
        }

        return returnObject;
    }

    @RequestMapping("/workbench/activity/detail")
    public String detail(String id, HttpServletRequest request) {
        Activity activity = activityService.queryActivityForDetailById(id);
        List<Remark> remarksList = remarkService.queryActivityRemarkForDetailByActivityId(id);
        request.setAttribute("activity",activity);
        request.setAttribute("remarksList",remarksList);
        return "workbench/activity/detail";

    }
}